home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / ncurses / cursesf.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-11-21  |  27.0 KB  |  968 lines

  1. // * This makes emacs happy -*-Mode: C++;-*-
  2. /****************************************************************************
  3.  * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc.              *
  4.  *                                                                          *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  6.  * copy of this software and associated documentation files (the            *
  7.  * "Software"), to deal in the Software without restriction, including      *
  8.  * without limitation the rights to use, copy, modify, merge, publish,      *
  9.  * distribute, distribute with modifications, sublicense, and/or sell       *
  10.  * copies of the Software, and to permit persons to whom the Software is    *
  11.  * furnished to do so, subject to the following conditions:                 *
  12.  *                                                                          *
  13.  * The above copyright notice and this permission notice shall be included  *
  14.  * in all copies or substantial portions of the Software.                   *
  15.  *                                                                          *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  19.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  22.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  23.  *                                                                          *
  24.  * Except as contained in this notice, the name(s) of the above copyright   *
  25.  * holders shall not be used in advertising or otherwise to promote the     *
  26.  * sale, use or other dealings in this Software without prior written       *
  27.  * authorization.                                                           *
  28.  ****************************************************************************/
  29.  
  30. /****************************************************************************
  31.  *   Author: Juergen Pfeifer, 1997                                          *
  32.  ****************************************************************************/
  33.  
  34. // $Id: cursesf.h,v 1.28 2005/08/13 18:08:24 tom Exp $
  35.  
  36. #ifndef NCURSES_CURSESF_H_incl
  37. #define NCURSES_CURSESF_H_incl 1
  38.  
  39. #include <cursesp.h>
  40.  
  41. #ifndef __EXT_QNX
  42. #include <string.h>
  43. #endif
  44.  
  45. extern "C" {
  46. #  include <form.h>
  47. }
  48. //
  49. // -------------------------------------------------------------------------
  50. // The abstract base class for buitin and user defined Fieldtypes.
  51. // -------------------------------------------------------------------------
  52. //
  53. class NCURSES_IMPEXP NCursesFormField; // forward declaration
  54.  
  55. // Class to represent builtin field types as well as C++ written new
  56. // fieldtypes (see classes UserDefineFieldType...
  57. class NCURSES_IMPEXP NCursesFieldType
  58. {
  59.   friend class NCursesFormField;
  60.  
  61. protected:
  62.   FIELDTYPE* fieldtype;
  63.  
  64.   inline void OnError(int err) const THROWS(NCursesFormException) {
  65.     if (err!=E_OK)
  66.       THROW(new NCursesFormException (err));
  67.   }
  68.  
  69.   NCursesFieldType(FIELDTYPE *f) : fieldtype(f) {
  70.   }
  71.  
  72.   virtual ~NCursesFieldType() {}
  73.  
  74.   // Set the fields f fieldtype to this one.
  75.   virtual void set(NCursesFormField& f) = 0;
  76.  
  77. public:
  78.   NCursesFieldType()
  79.     : fieldtype(STATIC_CAST(FIELDTYPE*)(0))
  80.   {
  81.   }
  82.  
  83.   NCursesFieldType& operator=(const NCursesFieldType& rhs)
  84.   {
  85.     if (this != &rhs) {
  86.       *this = rhs;
  87.     }
  88.     return *this;
  89.   }
  90.  
  91.   NCursesFieldType(const NCursesFieldType& rhs)
  92.     : fieldtype(rhs.fieldtype)
  93.   {
  94.   }
  95.  
  96. };
  97.  
  98. //
  99. // -------------------------------------------------------------------------
  100. // The class representing a forms field, wrapping the lowlevel FIELD struct
  101. // -------------------------------------------------------------------------
  102. //
  103. class NCURSES_IMPEXP NCursesFormField
  104. {
  105.   friend class NCursesForm;
  106.  
  107. protected:
  108.   FIELD *field;             // lowlevel structure
  109.   NCursesFieldType* ftype;   // Associated field type
  110.  
  111.   // Error handler
  112.   inline void OnError (int err) const THROWS(NCursesFormException) {
  113.     if (err != E_OK)
  114.       THROW(new NCursesFormException (err));
  115.   }
  116.  
  117. public:
  118.   // Create a 'Null' field. Can be used to delimit a field list
  119.   NCursesFormField()
  120.     : field(STATIC_CAST(FIELD*)(0)),
  121.       ftype(STATIC_CAST(NCursesFieldType*)(0))
  122.   {
  123.   }
  124.  
  125.   // Create a new field
  126.   NCursesFormField (int rows,
  127.             int ncols,
  128.             int first_row = 0,
  129.             int first_col = 0,
  130.             int offscreen_rows = 0,
  131.             int additional_buffers = 0)
  132.     : field(0),
  133.       ftype(STATIC_CAST(NCursesFieldType*)(0))
  134.   {
  135.       field = ::new_field(rows, ncols, first_row, first_col,
  136.               offscreen_rows, additional_buffers);
  137.       if (!field)
  138.     OnError(errno);
  139.   }
  140.  
  141.   NCursesFormField& operator=(const NCursesFormField& rhs)
  142.   {
  143.     if (this != &rhs) {
  144.       *this = rhs;
  145.     }
  146.     return *this;
  147.   }
  148.  
  149.   NCursesFormField(const NCursesFormField& rhs)
  150.     : field(rhs.field), ftype(rhs.ftype)
  151.   {
  152.   }
  153.  
  154.   virtual ~NCursesFormField ();
  155.  
  156.   // Duplicate the field at a new position
  157.   inline NCursesFormField* dup(int first_row, int first_col)
  158.   {
  159.     NCursesFormField* f = new NCursesFormField();
  160.     if (!f)
  161.       OnError(E_SYSTEM_ERROR);
  162.     else {
  163.       f->ftype = ftype;
  164.       f->field = ::dup_field(field,first_row,first_col);
  165.       if (!f->field)
  166.     OnError(errno);
  167.     }
  168.     return f;
  169.   }
  170.  
  171.   // Link the field to a new location
  172.   inline NCursesFormField* link(int first_row, int first_col) {
  173.     NCursesFormField* f = new NCursesFormField();
  174.     if (!f)
  175.       OnError(E_SYSTEM_ERROR);
  176.     else {
  177.       f->ftype = ftype;
  178.       f->field = ::link_field(field,first_row,first_col);
  179.       if (!f->field)
  180.     OnError(errno);
  181.     }
  182.     return f;
  183.   }
  184.  
  185.   // Get the lowlevel field representation
  186.   inline FIELD* get_field() const {
  187.     return field;
  188.   }
  189.  
  190.   // Retrieve info about the field
  191.   inline void info(int& rows, int& ncols,
  192.            int& first_row, int& first_col,
  193.            int& offscreen_rows, int& additional_buffers) const {
  194.     OnError(::field_info(field, &rows, &ncols,
  195.              &first_row, &first_col,
  196.              &offscreen_rows, &additional_buffers));
  197.   }
  198.  
  199.   // Retrieve info about the fields dynamic properties.
  200.   inline void dynamic_info(int& dynamic_rows, int& dynamic_cols,
  201.                int& max_growth) const {
  202.     OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols,
  203.                  &max_growth));
  204.   }
  205.  
  206.   // For a dynamic field you may set the maximum growth limit.
  207.   // A zero means unlimited growth.
  208.   inline void set_maximum_growth(int growth = 0) {
  209.     OnError(::set_max_field(field,growth));
  210.   }
  211.  
  212.   // Move the field to a new position
  213.   inline void move(int row, int col) {
  214.     OnError(::move_field(field,row,col));
  215.   }
  216.  
  217.   // Mark the field to start a new page
  218.   inline void new_page(bool pageFlag = FALSE) {
  219.     OnError(::set_new_page(field,pageFlag));
  220.   }
  221.  
  222.   // Retrieve whether or not the field starts a new page.
  223.   inline bool is_new_page() const {
  224.     return ::new_page(field);
  225.   }
  226.  
  227.   // Set the justification for the field
  228.   inline void set_justification(int just) {
  229.     OnError(::set_field_just(field,just));
  230.   }
  231.  
  232.   // Retrieve the fields justification
  233.   inline int justification() const {
  234.     return ::field_just(field);
  235.   }
  236.   // Set the foreground attribute for the field
  237.   inline void set_foreground(chtype foreground) {
  238.     OnError(::set_field_fore(field,foreground));
  239.   }
  240.  
  241.   // Retrieve the fields foreground attribute
  242.   inline chtype fore() const {
  243.     return ::field_fore(field);
  244.   }
  245.  
  246.   // Set the background attribute for the field
  247.   inline void set_background(chtype background) {
  248.     OnError(::set_field_back(field,background));
  249.   }
  250.  
  251.   // Retrieve the fields background attribute
  252.   inline chtype back() const {
  253.     return ::field_back(field);
  254.   }
  255.  
  256.   // Set the padding character for the field
  257.   inline void set_pad_character(int padding) {
  258.     OnError(::set_field_pad(field, padding));
  259.   }
  260.  
  261.   // Retrieve the fields padding character
  262.   inline int pad() const {
  263.     return ::field_pad(field);
  264.   }
  265.  
  266.   // Switch on the fields options
  267.   inline void options_on (Field_Options opts) {
  268.     OnError (::field_opts_on (field, opts));
  269.   }
  270.  
  271.   // Switch off the fields options
  272.   inline void options_off (Field_Options opts) {
  273.     OnError (::field_opts_off (field, opts));
  274.   }
  275.  
  276.   // Retrieve the fields options
  277.   inline Field_Options options () const {
  278.     return ::field_opts (field);
  279.   }
  280.  
  281.   // Set the fields options
  282.   inline void set_options (Field_Options opts) {
  283.     OnError (::set_field_opts (field, opts));
  284.   }
  285.  
  286.   // Mark the field as changed
  287.   inline void set_changed(bool changeFlag = TRUE) {
  288.     OnError(::set_field_status(field,changeFlag));
  289.   }
  290.  
  291.   // Test whether or not the field is marked as changed
  292.   inline bool changed() const {
  293.     return ::field_status(field);
  294.   }
  295.  
  296.   // Return the index of the field in the field array of a form
  297.   // or -1 if the field is not associated to a form
  298.   inline int (index)() const {
  299.     return ::field_index(field);
  300.   }
  301.  
  302.   // Store a value in a fields buffer. The default buffer is nr. 0
  303.   inline void set_value(const char *val, int buffer = 0) {
  304.     OnError(::set_field_buffer(field,buffer,val));
  305.   }
  306.  
  307.   // Retrieve the value of a fields buffer. The default buffer is nr. 0
  308.   inline char* value(int buffer = 0) const {
  309.     return ::field_buffer(field,buffer);
  310.   }
  311.  
  312.   // Set the validation type of the field.
  313.   inline void set_fieldtype(NCursesFieldType& f) {
  314.     ftype = &f;
  315.     f.set(*this); // A good friend may do that...
  316.   }
  317.  
  318.   // Retrieve the validation type of the field.
  319.   inline NCursesFieldType* fieldtype() const {
  320.     return ftype;
  321.   }
  322.  
  323. };
  324.  
  325.   // This are the built-in hook functions in this C++ binding. In C++ we use
  326.   // virtual member functions (see below On_..._Init and On_..._Termination)
  327.   // to provide this functionality in an object oriented manner.
  328. extern "C" {
  329.   void _nc_xx_frm_init(FORM *);
  330.   void _nc_xx_frm_term(FORM *);
  331.   void _nc_xx_fld_init(FORM *);
  332.   void _nc_xx_fld_term(FORM *);
  333. }
  334.  
  335. //
  336. // -------------------------------------------------------------------------
  337. // The class representing a form, wrapping the lowlevel FORM struct
  338. // -------------------------------------------------------------------------
  339. //
  340. class NCURSES_IMPEXP NCursesForm : public NCursesPanel
  341. {
  342. protected:
  343.   FORM* form;  // the lowlevel structure
  344.  
  345. private:
  346.   NCursesWindow* sub;   // the subwindow object
  347.   bool b_sub_owner;     // is this our own subwindow?
  348.   bool b_framed;    // has the form a border?
  349.   bool b_autoDelete;    // Delete fields when deleting form?
  350.  
  351.   NCursesFormField** my_fields; // The array of fields for this form
  352.  
  353.   // This structure is used for the form's user data field to link the
  354.   // FORM* to the C++ object and to provide extra space for a user pointer.
  355.   typedef struct {
  356.     void*           m_user;        // the pointer for the user's data
  357.     const NCursesForm* m_back;      // backward pointer to C++ object
  358.     const FORM*           m_owner;
  359.   } UserHook;
  360.  
  361.   // Get the backward pointer to the C++ object from a FORM
  362.   static inline NCursesForm* getHook(const FORM *f) {
  363.     UserHook* hook = reinterpret_cast<UserHook*>(::form_userptr(f));
  364.     assert(hook != 0 && hook->m_owner==f);
  365.     return const_cast<NCursesForm*>(hook->m_back);
  366.   }
  367.  
  368.   friend void _nc_xx_frm_init(FORM *);
  369.   friend void _nc_xx_frm_term(FORM *);
  370.   friend void _nc_xx_fld_init(FORM *);
  371.   friend void _nc_xx_fld_term(FORM *);
  372.  
  373.   // Calculate FIELD* array for the menu
  374.   FIELD** mapFields(NCursesFormField* nfields[]);
  375.  
  376. protected:
  377.   // internal routines
  378.   inline void set_user(void *user) {
  379.     UserHook* uptr = reinterpret_cast<UserHook*>(::form_userptr (form));
  380.     assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form);
  381.     uptr->m_user = user;
  382.   }
  383.  
  384.   inline void *get_user() {
  385.     UserHook* uptr = reinterpret_cast<UserHook*>(::form_userptr (form));
  386.     assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form);
  387.     return uptr->m_user;
  388.   }
  389.  
  390.   void InitForm (NCursesFormField* Fields[],
  391.          bool with_frame,
  392.          bool autoDeleteFields);
  393.  
  394.   inline void OnError (int err) const THROWS(NCursesFormException) {
  395.     if (err != E_OK)
  396.       THROW(new NCursesFormException (err));
  397.   }
  398.  
  399.   // this wraps the form_driver call.
  400.   virtual int driver (int c) ;
  401.  
  402.   // 'Internal' constructor, builds an object without association to a
  403.   // field array.
  404.   NCursesForm( int  nlines,
  405.            int  ncols,
  406.            int  begin_y = 0,
  407.            int  begin_x = 0)
  408.     : NCursesPanel(nlines, ncols, begin_y, begin_x),
  409.       form (STATIC_CAST(FORM*)(0)),
  410.       sub(0),
  411.       b_sub_owner(0),
  412.       b_framed(0),
  413.       b_autoDelete(0),
  414.       my_fields(0)
  415.   {
  416.   }
  417.  
  418. public:
  419.   // Create form for the default panel.
  420.   NCursesForm (NCursesFormField* Fields[],
  421.            bool with_frame=FALSE,          // reserve space for a frame?
  422.            bool autoDelete_Fields=FALSE)  // do automatic cleanup?
  423.     : NCursesPanel(),
  424.       form(0),
  425.       sub(0),
  426.       b_sub_owner(0),
  427.       b_framed(0),
  428.       b_autoDelete(0),
  429.       my_fields(0)
  430.   {
  431.     InitForm(Fields, with_frame, autoDelete_Fields);
  432.   }
  433.  
  434.   // Create a form in a panel with the given position and size.
  435.   NCursesForm (NCursesFormField* Fields[],
  436.            int  nlines,
  437.            int  ncols,
  438.            int  begin_y,
  439.            int  begin_x,
  440.            bool with_frame=FALSE,         // reserve space for a frame?
  441.            bool autoDelete_Fields=FALSE) // do automatic cleanup?
  442.     : NCursesPanel(nlines, ncols, begin_y, begin_x),
  443.       form(0),
  444.       sub(0),
  445.       b_sub_owner(0),
  446.       b_framed(0),
  447.       b_autoDelete(0),
  448.       my_fields(0)
  449.   {
  450.       InitForm(Fields, with_frame, autoDelete_Fields);
  451.   }
  452.  
  453.   NCursesForm& operator=(const NCursesForm& rhs)
  454.   {
  455.     if (this != &rhs) {
  456.       *this = rhs;
  457.       NCursesPanel::operator=(rhs);
  458.     }
  459.     return *this;
  460.   }
  461.  
  462.   NCursesForm(const NCursesForm& rhs)
  463.     : NCursesPanel(rhs),
  464.       form(rhs.form),
  465.       sub(rhs.sub),
  466.       b_sub_owner(rhs.b_sub_owner),
  467.       b_framed(rhs.b_framed),
  468.       b_autoDelete(rhs.b_autoDelete),
  469.       my_fields(rhs.my_fields)
  470.   {
  471.   }
  472.  
  473.   virtual ~NCursesForm();
  474.  
  475.   // Set the default attributes for the form
  476.   virtual void setDefaultAttributes();
  477.  
  478.   // Retrieve current field of the form.
  479.   inline NCursesFormField* current_field() const {
  480.     return my_fields[::field_index(::current_field(form))];
  481.   }
  482.  
  483.   // Set the forms subwindow
  484.   void setSubWindow(NCursesWindow& sub);
  485.  
  486.   // Set these fields for the form
  487.   inline void setFields(NCursesFormField* Fields[]) {
  488.     OnError(::set_form_fields(form,mapFields(Fields)));
  489.   }
  490.  
  491.   // Remove the form from the screen
  492.   inline void unpost (void) {
  493.     OnError (::unpost_form (form));
  494.   }
  495.  
  496.   // Post the form to the screen if flag is true, unpost it otherwise
  497.   inline void post(bool flag = TRUE) {
  498.     OnError (flag ? ::post_form(form) : ::unpost_form (form));
  499.   }
  500.  
  501.   // Decorations
  502.   inline void frame(const char *title=NULL, const char* btitle=NULL) {
  503.     if (b_framed)
  504.       NCursesPanel::frame(title,btitle);
  505.     else
  506.       OnError(E_SYSTEM_ERROR);
  507.   }
  508.  
  509.   inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
  510.     if (b_framed)
  511.       NCursesPanel::boldframe(title,btitle);
  512.     else
  513.       OnError(E_SYSTEM_ERROR);
  514.   }
  515.  
  516.   inline void label(const char *topLabel, const char *bottomLabel) {
  517.     if (b_framed)
  518.       NCursesPanel::label(topLabel,bottomLabel);
  519.     else
  520.       OnError(E_SYSTEM_ERROR);
  521.   }
  522.  
  523.   // -----
  524.   // Hooks
  525.   // -----
  526.  
  527.   // Called after the form gets repositioned in its window.
  528.   // This is especially true if the form is posted.
  529.   virtual void On_Form_Init();
  530.  
  531.   // Called before the form gets repositioned in its window.
  532.   // This is especially true if the form is unposted.
  533.   virtual void On_Form_Termination();
  534.  
  535.   // Called after the field became the current field
  536.   virtual void On_Field_Init(NCursesFormField& field);
  537.  
  538.   // Called before this field is left as current field.
  539.   virtual void On_Field_Termination(NCursesFormField& field);
  540.  
  541.   // Calculate required window size for the form.
  542.   void scale(int& rows, int& ncols) const {
  543.     OnError(::scale_form(form,&rows,&ncols));
  544.   }
  545.  
  546.   // Retrieve number of fields in the form.
  547.   int count() const {
  548.     return ::field_count(form);
  549.   }
  550.  
  551.   // Make the page the current page of the form.
  552.   void set_page(int pageNum) {
  553.     OnError(::set_form_page(form, pageNum));
  554.   }
  555.  
  556.   // Retrieve current page number
  557.   int page() const {
  558.     return ::form_page(form);
  559.   }
  560.  
  561.   // Switch on the forms options
  562.   inline void options_on (Form_Options opts) {
  563.     OnError (::form_opts_on (form, opts));
  564.   }
  565.  
  566.   // Switch off the forms options
  567.   inline void options_off (Form_Options opts) {
  568.     OnError (::form_opts_off (form, opts));
  569.   }
  570.  
  571.   // Retrieve the forms options
  572.   inline Form_Options options () const {
  573.     return ::form_opts (form);
  574.   }
  575.  
  576.   // Set the forms options
  577.   inline void set_options (Form_Options opts) {
  578.     OnError (::set_form_opts (form, opts));
  579.   }
  580.  
  581.   // Are there more data in the current field after the data shown
  582.   inline bool data_ahead() const {
  583.     return ::data_ahead(form);
  584.   }
  585.  
  586.   // Are there more data in the current field before the data shown
  587.   inline bool data_behind() const {
  588.     return ::data_behind(form);
  589.   }
  590.  
  591.   // Position the cursor to the current field
  592.   inline void position_cursor () {
  593.     OnError (::pos_form_cursor (form));
  594.   }
  595.   // Set the current field
  596.   inline void set_current(NCursesFormField& F) {
  597.     OnError (::set_current_field(form, F.field));
  598.   }
  599.  
  600.   // Provide a default key virtualization. Translate the keyboard
  601.   // code c into a form request code.
  602.   // The default implementation provides a hopefully straightforward
  603.   // mapping for the most common keystrokes and form requests.
  604.   virtual int virtualize(int c);
  605.  
  606.   // Operators
  607.   inline NCursesFormField* operator[](int i) const {
  608.     if ( (i < 0) || (i >= ::field_count (form)) )
  609.       OnError (E_BAD_ARGUMENT);
  610.     return my_fields[i];
  611.   }
  612.  
  613.   // Perform the menu's operation
  614.   // Return the field where you left the form.
  615.   virtual NCursesFormField* operator()(void);
  616.  
  617.   // Exception handlers. The default is a Beep.
  618.   virtual void On_Request_Denied(int c) const;
  619.   virtual void On_Invalid_Field(int c) const;
  620.   virtual void On_Unknown_Command(int c) const;
  621.  
  622. };
  623.  
  624. //
  625. // -------------------------------------------------------------------------
  626. // This is the typical C++ typesafe way to allow to attach
  627. // user data to a field of a form. Its assumed that the user
  628. // data belongs to some class T. Use T as template argument
  629. // to create a UserField.
  630. // -------------------------------------------------------------------------
  631. template<class T> class NCURSES_IMPEXP NCursesUserField : public NCursesFormField
  632. {
  633. public:
  634.   NCursesUserField (int rows,
  635.             int ncols,
  636.             int first_row = 0,
  637.             int first_col = 0,
  638.             const T* p_UserData = STATIC_CAST(T*)(0),
  639.             int offscreen_rows = 0,
  640.             int additional_buffers = 0)
  641.     : NCursesFormField (rows, ncols,
  642.             first_row, first_col,
  643.             offscreen_rows, additional_buffers) {
  644.       if (field)
  645.     OnError(::set_field_userptr(field, STATIC_CAST(void *)(p_UserData)));
  646.   }
  647.  
  648.   virtual ~NCursesUserField() {};
  649.  
  650.   inline const T* UserData (void) const {
  651.     return reinterpret_cast<const T*>(::field_userptr (field));
  652.   }
  653.  
  654.   inline virtual void setUserData(const T* p_UserData) {
  655.     if (field)
  656.       OnError (::set_field_userptr (field, STATIC_CAST(void *)(p_UserData)));
  657.   }
  658. };
  659. //
  660. // -------------------------------------------------------------------------
  661. // The same mechanism is used to attach user data to a form
  662. // -------------------------------------------------------------------------
  663. //
  664. template<class T> class NCURSES_IMPEXP NCursesUserForm : public NCursesForm
  665. {
  666. protected:
  667.   // 'Internal' constructor, builds an object without association to a
  668.   // field array.
  669.   NCursesUserForm( int  nlines,
  670.            int  ncols,
  671.            int  begin_y = 0,
  672.            int  begin_x = 0,
  673.            const T* p_UserData = STATIC_CAST(T*)(0))
  674.     : NCursesForm(nlines,ncols,begin_y,begin_x) {
  675.       if (form)
  676.     set_user (const_cast<void *>(p_UserData));
  677.   }
  678.  
  679. public:
  680.   NCursesUserForm (NCursesFormField Fields[],
  681.            const T* p_UserData = STATIC_CAST(T*)(0),
  682.            bool with_frame=FALSE,
  683.            bool autoDelete_Fields=FALSE)
  684.     : NCursesForm (Fields, with_frame, autoDelete_Fields) {
  685.       if (form)
  686.     set_user (const_cast<void *>(p_UserData));
  687.   };
  688.  
  689.   NCursesUserForm (NCursesFormField Fields[],
  690.            int nlines,
  691.            int ncols,
  692.            int begin_y = 0,
  693.            int begin_x = 0,
  694.            const T* p_UserData = STATIC_CAST(T*)(0),
  695.            bool with_frame=FALSE,
  696.            bool autoDelete_Fields=FALSE)
  697.     : NCursesForm (Fields, nlines, ncols, begin_y, begin_x,
  698.            with_frame, autoDelete_Fields) {
  699.       if (form)
  700.     set_user (const_cast<void *>(p_UserData));
  701.   };
  702.  
  703.   virtual ~NCursesUserForm() {
  704.   };
  705.  
  706.   inline T* UserData (void) const {
  707.     return reinterpret_cast<T*>(get_user ());
  708.   };
  709.  
  710.   inline virtual void setUserData (const T* p_UserData) {
  711.     if (form)
  712.       set_user (const_cast<void *>(p_UserData));
  713.   }
  714.  
  715. };
  716. //
  717. // -------------------------------------------------------------------------
  718. // Builtin Fieldtypes
  719. // -------------------------------------------------------------------------
  720. //
  721. class NCURSES_IMPEXP Alpha_Field : public NCursesFieldType
  722. {
  723. private:
  724.   int min_field_width;
  725.  
  726.   void set(NCursesFormField& f) {
  727.     OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
  728.   }
  729.  
  730. public:
  731.   Alpha_Field(int width)
  732.     : NCursesFieldType(TYPE_ALPHA),
  733.       min_field_width(width) {
  734.   }
  735. };
  736.  
  737. class NCURSES_IMPEXP Alphanumeric_Field : public NCursesFieldType
  738. {
  739. private:
  740.   int min_field_width;
  741.  
  742.   void set(NCursesFormField& f) {
  743.     OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
  744.   }
  745.  
  746. public:
  747.   Alphanumeric_Field(int width)
  748.     : NCursesFieldType(TYPE_ALNUM),
  749.       min_field_width(width) {
  750.   }
  751. };
  752.  
  753. class NCURSES_IMPEXP Integer_Field : public NCursesFieldType
  754. {
  755. private:
  756.   int precision;
  757.   long lower_limit, upper_limit;
  758.  
  759.   void set(NCursesFormField& f) {
  760.     OnError(::set_field_type(f.get_field(),fieldtype,
  761.                  precision,lower_limit,upper_limit));
  762.   }
  763.  
  764. public:
  765.   Integer_Field(int prec, long low=0L, long high=0L)
  766.     : NCursesFieldType(TYPE_INTEGER),
  767.       precision(prec), lower_limit(low), upper_limit(high) {
  768.   }
  769. };
  770.  
  771. class NCURSES_IMPEXP Numeric_Field : public NCursesFieldType
  772. {
  773. private:
  774.   int precision;
  775.   double lower_limit, upper_limit;
  776.  
  777.   void set(NCursesFormField& f) {
  778.     OnError(::set_field_type(f.get_field(),fieldtype,
  779.                  precision,lower_limit,upper_limit));
  780.   }
  781.  
  782. public:
  783.   Numeric_Field(int prec, double low=0.0, double high=0.0)
  784.     : NCursesFieldType(TYPE_NUMERIC),
  785.       precision(prec), lower_limit(low), upper_limit(high) {
  786.   }
  787. };
  788.  
  789. class NCURSES_IMPEXP Regular_Expression_Field : public NCursesFieldType
  790. {
  791. private:
  792.   char* regex;
  793.  
  794.   void set(NCursesFormField& f) {
  795.     OnError(::set_field_type(f.get_field(),fieldtype,regex));
  796.   }
  797.  
  798.   void copy_regex(const char *source)
  799.   {
  800.     regex = new char[1 + ::strlen(source)];
  801.     (::strcpy)(regex, source);
  802.   }
  803.  
  804. public:
  805.   Regular_Expression_Field(const char *expr)
  806.     : NCursesFieldType(TYPE_REGEXP),
  807.       regex(NULL)
  808.   {
  809.     copy_regex(expr);
  810.   }
  811.  
  812.   Regular_Expression_Field& operator=(const Regular_Expression_Field& rhs)
  813.   {
  814.     if (this != &rhs) {
  815.       *this = rhs;
  816.       copy_regex(rhs.regex);
  817.       NCursesFieldType::operator=(rhs);
  818.     }
  819.     return *this;
  820.   }
  821.  
  822.   Regular_Expression_Field(const Regular_Expression_Field& rhs)
  823.     : NCursesFieldType(rhs),
  824.       regex(NULL)
  825.   {
  826.     copy_regex(rhs.regex);
  827.   }
  828.  
  829.   ~Regular_Expression_Field() {
  830.     delete[] regex;
  831.   }
  832. };
  833.  
  834. class NCURSES_IMPEXP Enumeration_Field : public NCursesFieldType
  835. {
  836. private:
  837.   const char** list;
  838.   int case_sensitive;
  839.   int non_unique_matches;
  840.  
  841.   void set(NCursesFormField& f) {
  842.     OnError(::set_field_type(f.get_field(),fieldtype,
  843.                  list,case_sensitive,non_unique_matches));
  844.   }
  845. public:
  846.   Enumeration_Field(const char* enums[],
  847.             bool case_sens=FALSE,
  848.             bool non_unique=FALSE)
  849.     : NCursesFieldType(TYPE_ENUM),
  850.       list(enums),
  851.       case_sensitive(case_sens ? -1 : 0),
  852.       non_unique_matches(non_unique ? -1 : 0) {
  853.   }
  854.  
  855.   Enumeration_Field& operator=(const Enumeration_Field& rhs)
  856.   {
  857.     if (this != &rhs) {
  858.       *this = rhs;
  859.       NCursesFieldType::operator=(rhs);
  860.     }
  861.     return *this;
  862.   }
  863.  
  864.   Enumeration_Field(const Enumeration_Field& rhs)
  865.     : NCursesFieldType(rhs),
  866.       list(rhs.list),
  867.       case_sensitive(rhs.case_sensitive),
  868.       non_unique_matches(rhs.non_unique_matches)
  869.   {
  870.   }
  871. };
  872.  
  873. class NCURSES_IMPEXP IPV4_Address_Field : public NCursesFieldType
  874. {
  875. private:
  876.   void set(NCursesFormField& f) {
  877.     OnError(::set_field_type(f.get_field(),fieldtype));
  878.   }
  879.  
  880. public:
  881.   IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) {
  882.   }
  883. };
  884.  
  885. extern "C" {
  886.   bool _nc_xx_fld_fcheck(FIELD *, const void*);
  887.   bool _nc_xx_fld_ccheck(int c, const void *);
  888.   void* _nc_xx_fld_makearg(va_list*);
  889. }
  890.  
  891. //
  892. // -------------------------------------------------------------------------
  893. // Abstract base class for User-Defined Fieldtypes
  894. // -------------------------------------------------------------------------
  895. //
  896. class NCURSES_IMPEXP UserDefinedFieldType : public NCursesFieldType
  897. {
  898.   friend class UDF_Init; // Internal helper to set up statics
  899. private:
  900.   // For all C++ defined fieldtypes we need only one generic lowlevel
  901.   // FIELDTYPE* element.
  902.   static FIELDTYPE* generic_fieldtype;
  903.  
  904. protected:
  905.   // This are the functions required by the low level libforms functions
  906.   // to construct a fieldtype.
  907.   friend bool _nc_xx_fld_fcheck(FIELD *, const void*);
  908.   friend bool _nc_xx_fld_ccheck(int c, const void *);
  909.   friend void* _nc_xx_fld_makearg(va_list*);
  910.  
  911.   void set(NCursesFormField& f) {
  912.     OnError(::set_field_type(f.get_field(),fieldtype,&f));
  913.   }
  914.  
  915. protected:
  916.   // Redefine this function to do a field validation. The argument
  917.   // is a reference to the field you should validate.
  918.   virtual bool field_check(NCursesFormField& f) = 0;
  919.  
  920.   // Redefine this function to do a character validation. The argument
  921.   // is the character to be validated.
  922.   virtual bool char_check (int c) = 0;
  923.  
  924. public:
  925.   UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) {
  926.   }
  927. };
  928.  
  929. extern "C" {
  930.   bool _nc_xx_next_choice(FIELD*, const void *);
  931.   bool _nc_xx_prev_choice(FIELD*, const void *);
  932. }
  933.  
  934. //
  935. // -------------------------------------------------------------------------
  936. // Abstract base class for User-Defined Fieldtypes with Choice functions
  937. // -------------------------------------------------------------------------
  938. //
  939. class NCURSES_IMPEXP UserDefinedFieldType_With_Choice : public UserDefinedFieldType
  940. {
  941.   friend class UDF_Init; // Internal helper to set up statics
  942. private:
  943.   // For all C++ defined fieldtypes with choice functions we need only one
  944.   // generic lowlevel FIELDTYPE* element.
  945.   static FIELDTYPE* generic_fieldtype_with_choice;
  946.  
  947.   // This are the functions required by the low level libforms functions
  948.   // to construct a fieldtype with choice functions.
  949.   friend bool _nc_xx_next_choice(FIELD*, const void *);
  950.   friend bool _nc_xx_prev_choice(FIELD*, const void *);
  951.  
  952. protected:
  953.   // Redefine this function to do the retrieval of the next choice value.
  954.   // The argument is a reference to the field tobe examined.
  955.   virtual bool next    (NCursesFormField& f) = 0;
  956.  
  957.   // Redefine this function to do the retrieval of the previous choice value.
  958.   // The argument is a reference to the field tobe examined.
  959.   virtual bool previous(NCursesFormField& f) = 0;
  960.  
  961. public:
  962.   UserDefinedFieldType_With_Choice() {
  963.     fieldtype = generic_fieldtype_with_choice;
  964.   }
  965. };
  966.  
  967. #endif /* NCURSES_CURSESF_H_incl */
  968.